#include <iostream>
#include <string>
#include <fstream>
#include <chrono>
#include "../pbcxx.h"
#include "../json.hpp"
#include "utils.h"

using namespace std;

void setFiles(int num, nlohmann::json& dbJson, pair_class* &pairing, vector<RsaAcc>& Acc, vector<ele_class>& V, VectorCommitment* &VC) {
    assert(num > 0);
    using namespace nlohmann;
    json allFilesJson;
    string allFilesJsonPath = "../files.json";
    ifstream is_all_files(allFilesJsonPath);
    is_all_files >> allFilesJson;
    is_all_files.close();

    // 从全部文件集里读取前 num 个
    json& fileJson = dbJson["DB"];
    fileJson.clear();
    for (int i = 0; i < num; i++) {
        json file = allFilesJson[i];
        for (auto word_it = file["keywords"].begin(); word_it != file["keywords"].end(); ++word_it) {
            string word = (*word_it).get<string>();
            Update(i, word, "add", dbJson, pairing, Acc, V, VC);
        }
        string fileName = "file" + to_string(i);
        file["name"] = fileName;
        fileJson.push_back(file);
    }
}

int main() {
    using namespace nlohmann;
    string vdsseJsonPath = "vdsse.json";
    json vdsseJson;
    ifstream ifs_vdsse(vdsseJsonPath);
    ifs_vdsse >> vdsseJson;

    auto start = chrono::steady_clock::now();
    chrono::duration<double> dura;
    dura = chrono::steady_clock::now() - start;
    cout << "begin: " << dura.count() << endl;

    pair_class* pairing = nullptr;
    VectorCommitment* VC = nullptr;
    vector<RsaAcc> Acc;
    vector<ele_class> V;
    Setup(vdsseJson, pairing, Acc, V, 50, VC);

    dura = chrono::steady_clock::now() - start;
    cout << "setup use: " << dura.count() << endl;


    setFiles(100, vdsseJson, pairing, Acc, V, VC);

    dura = chrono::steady_clock::now() - start;
    cout << "setfiles use: " << dura.count() << endl;

    Search("thank", vdsseJson, Acc, V, VC);

    dura = chrono::steady_clock::now() - start;
    cout << "search use: " << dura.count() << endl;

    Verify("thank", vdsseJson, Acc, V, VC);

    dura = chrono::steady_clock::now() - start;
    cout << "verify use: " << dura.count() << endl;
    // RsaAcc rsa(pairing);
    // rsa.insert("aaa");
    // rsa.insert("bbb");
    // ele_class acc = rsa.get_acc();
    // cout << acc.to_string() << endl;
    // ele_class wit = rsa.memWitAdd("aaa");
    // cout << rsa.checkWit("aaa", wit) << endl;
    // cout << rsa.checkWit("ccc", wit) << endl;


    // ele_class p(pairing, "Zr");
    // p.set_str("730750818665451621361119245571504901405976559617");

    // VectorCommitment vc(200, vdsseJson);

    // vector<ele_class> M;
    // for (int i = 0; i < 10; ++i) {
    //     ele_class t(pairing, "Zr");
    //     t.random();
    //     M.push_back(t);
    // }
    // cout << vc.commit(M.begin(), M.end()).to_string() << endl;

    // mpz_class a = 256;
    // a ^= 256;
    // cout << a << endl;

    // string param = VC_json["param"].get<string>();
    // pair_class pairing(param);
    // ele_class g1(pairing, "G1");
    // g1.random();
    // VC_json["g1"] = g1.to_string();
    // ele_class g2(pairing, "G2");
    // g2.random();
    // VC_json["g2"] = g2.to_string();
    // ele_class alpha(pairing, "Zr");
    // alpha.random();
    // VC_json["alpha"] = alpha.to_string();

    ofstream o(vdsseJsonPath);
    o << setw(2) << vdsseJson << endl;
}
